home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
emerald
/
emrldsys.lha
/
Language
/
Compiler
/
sugar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-16
|
21KB
|
757 lines
/*
* @(#)sugar.c 1.9 2/23/90
*/
#include "assert.h"
#include "error.h"
#include "scan.h"
#include "nodes.h"
#include "symbols.h"
#include "MyParser.h"
#include "semantics.h"
#include "system.h"
#include "builtins.h"
#include "flags.h"
#include "sequence.h"
#include "opNames.h"
#define NN ((NodePtr) NULL)
extern NodePtr buildString();
#define BSR(P,I) buildSymbol(P_SYMREF, P, I)
#define BSD(P,I) buildSymbol(P_SYMDEF, P, I)
#define BON(P,I) buildOpName(P, I)
static NodePtr buildS(), _buildS(), buildSignature(), _buildSignature(),
buildBlock(), _buildBlock();
static NodePtr builtinPAT, builtinBoolean, builtinAny, builtinInteger,
builtinNode;
NodePtr copySig(p)
register NodePtr p;
{
register NodePtr result;
register int i;
if (ISTOKEN(p)) return(p);
result = F_NewNode(p->tag, p->nChildren-p->firstChild);
result->nChildren = p->nChildren;
for (i = 0; i < p->firstChild; i++) {
result->b.children[i] = p->b.children[i];
}
if (p->tag == P_PARAM) {
result->b.param.sym = copySig(p->b.param.sym);
result->b.param.type = p->b.param.type;
result->b.param.constraint = p->b.param.constraint;
} else {
for (i = p->firstChild; i < p->nChildren; i++) {
result->b.children[i] = copySig(p->b.children[i]);
}
}
return(result);
}
void init_Sugar()
{
builtinPAT = Construct(P_BUILTINLIT, 0);
builtinPAT->b.builtinlit.whichType = KSIGNATURE;
builtinBoolean = Construct(P_BUILTINLIT, 0);
builtinBoolean->b.builtinlit.whichType = KBOOLEAN;
builtinAny = Construct(P_BUILTINLIT, 0);
builtinAny->b.builtinlit.whichType = KANY;
builtinInteger = Construct(P_BUILTINLIT, 0);
builtinInteger->b.builtinlit.whichType = KINTEGER;
builtinNode = Construct(P_BUILTINLIT, 0);
builtinNode->b.builtinlit.whichType = KNODE;
}
static NodePtr buildIntegerLiteral(n)
int n;
{
char *string;
NodePtr result;
string = (char *) malloc(10);
(void) sprintf(string, "%d", n);
result = Construct(P_INTLIT, 0);
result->b.intlit.string = string;
return(result);
}
NodePtr buildComplicatedSymbol(tag, prefix, ident, suffix)
Tag tag;
char *prefix, *suffix;
Ident ident;
{
register char *buf;
register char *name;
register NodePtr p;
p = Construct(tag, 0);
name = ident == 0 ? "" : Ident_Name(ident);
buf = (char *)
malloc((unsigned)(strlen(prefix)+strlen(suffix)+strlen(name)+10));
(void) sprintf(buf, "%s%s%s", prefix, name, suffix);
p->b.symdef.ident = Ident_Lookup(buf, strlen(buf));
free(buf);
return(p);
}
extern Boolean opNamesResolved;
NodePtr buildOpName(prefix, i)
char *prefix;
Ident i;
{
register char *old, *new;
register NodePtr p;
p = Construct(P_OPNAME, 0);
if (i <= 0) old = "";
else old = Ident_Name(i);
new = (char *) malloc((unsigned)(strlen(old)+strlen(prefix)+1));
(void) strcpy(new, prefix);
(void) strcat(new, old);
p->b.opname.ident = Ident_Lookup(new, strlen(new));
if (opNamesResolved) p->b.opname.id = ON_Translate(new);
Free(new);
return(p);
}
static NodePtr _buildInvocation(target, opName, n, args)
NodePtr target, opName;
register NodePtr *args;
int n;
{
register int i;
register NodePtr params;
if (n == 0) params = NN;
else {
params = F_NewNode(T_SEQUENCE, n);
params->nChildren = n;
for (i = 0; i < n; i++) {
params->b.children[i] = Construct(P_ARG, 1, args[i]);
}
}
return(Construct(P_INVOC, 3, target, opName, params));
}
/*VARARGS3*/
static NodePtr buildInvocation(target, opName, n, firstParameter)
NodePtr target, opName, firstParameter;
int n;
{
return _buildInvocation(target, opName, n, &firstParameter);
}
NodePtr buildSymbol(tag, prefix, index)
Tag tag;
char *prefix;
int index;
{
register char *buf;
register NodePtr p;
p = Construct(tag, 0);
buf = (char *) malloc((unsigned)(strlen(prefix)+20));
if (index < 0) (void) strcpy(buf, prefix);
else (void) sprintf(buf, "%s__%d", prefix, index);
p->b.symdef.ident = Ident_Lookup(buf, strlen(buf));
free(buf);
return(p);
}
void removeSugar(fNodePtr)
NodePtr *fNodePtr;
{
NodePtr instanceAT, opSigSeq, typeO, instanceO, od, s1, s2, sig,
monitorO, varDecls, opDecls, exportSeq, iAT, block;
int numFields;
register NodePtr thisField;
NodePtr *argvec, createSig;
register NodePtr p, r, l, result = NN;
NodePtr name, args, assignedValue;
register int i;
Boolean isImmutable, isSugared;
int factor;
p = *fNodePtr;
if (p == NN) {
return;
} else if ((int)p < 0x200) {
/* it is probably an input token */
return;
} else {
nextLineNumber = p->lineNumber;
switch (p->tag) {
case P_COMP:
if (!bflag) {
r = Construct(P_INVOC, 3,
builtinNode,
buildOpName("getStdin", -1),
NN);
r = Construct(P_CONSTDECL, 3,
buildSymbol(P_SYMDEF, "stdin", -1),
NN,
r);
Sequence_AddFirst(&p->b.comp.consts, r);
r = Construct(P_INVOC, 3,
builtinNode,
buildOpName("getStdout", -1),
NN);
r = Construct(P_CONSTDECL, 3,
buildSymbol(P_SYMDEF, "stdout", -1),
NN,
r);
Sequence_AddFirst(&p->b.comp.consts, r);
}
break;
case P_ASSIGNSTAT:
assert(isASequence(p->b.assignstat.left));
assert(isASequence(p->b.assignstat.right));
isSugared = FALSE;
Sequence_For(l, p->b.assignstat.left)
if (l->tag == P_SUBSCRIPT || l->tag == P_FIELDSEL) isSugared = TRUE;
Sequence_Next
if (isSugared &&
(p->b.assignstat.left->nChildren != 1 ||
p->b.assignstat.right->nChildren != 1)) {
BeginErrorMessage(p->b.assignstat.left);
ErrorWrite("Illegal sugared assignment");
EndErrorMessage();
break;
} else if (!isSugared) {
p->b.assignstat.op = OASSIGN;
break;
}
/*
* We only get here if we have a sugared assign with one thing on
* the left.
*/
r = p->b.assignstat.left->b.children[0];
/*
* Now r points to the expression that we are assigning
* to.
*/
assignedValue =
Construct(P_ARG, 1, p->b.assignstat.right->b.children[0]);
Free(p->b.assignstat.right);
Free(p->b.assignstat.left);
if (r->tag == P_SUBSCRIPT) {
name = BON("setelement", -1);
args = r->b.subscript.exp;
Sequence_Add(&args, assignedValue);
result = Construct(P_INVOC, 3, r->b.subscript.target,
name, args);
} else if (r->tag == P_FIELDSEL) {
name = BON("set", r->b.fieldsel.fieldref->b.fieldref.ident);
args = Construct(T_SEQUENCE, 1, assignedValue);
result = Construct(P_INVOC, 3, r->b.fieldsel.target,
name, args);
} else {
assert(FALSE);
}
Free(r);
p->b.assignstat.left = NULL;
p->b.assignstat.op = OASSIGN;
p->b.assignstat.right = Construct(T_SEQUENCE, 1, result);
break;
case P_FIELDSEL:
name = BON("get", p->b.fieldsel.fieldref->b.fieldref.ident);
args = NN;
result = Construct(P_INVOC, 3, p->b.fieldsel.target, name, args);
Free(p);
*fNodePtr = result;
break;
case P_SUBSCRIPT:
name = BON("getelement", -1);
args = p->b.subscript.exp;
result = Construct(P_INVOC, 3, p->b.subscript.target, name, args);
Free(p);
*fNodePtr = result;
break;
case P_ENUMLIT:
typeO = F_NewNode(P_OBLIT, 10);
typeO->nChildren += 10;
typeO->b.oblit.sfname = buildString(currentFileName);
typeO->b.oblit.name = BSD("enum", 0);
assert(p->b.enumlit.syms->tag == T_SEQUENCE);
numFields = p->b.enumlit.syms->nChildren;
argvec = (NodePtr *) malloc((unsigned)(sizeof(NodePtr)*(numFields+4)));
argvec[0] = BON("getsignature", -1);
argvec[1] = BON("create", -1);
argvec[2] = BON("first", -1);
argvec[3] = BON("last", -1);
for (i = 0; i < numFields; i++) {
thisField = p->b.enumlit.syms->b.children[i];
assert(thisField->tag == P_SYMDEF);
argvec[4+i] = BON(Ident_Name(thisField->b.symdef.ident), -1);
}
typeO->b.oblit.export =
Construct(P_EXPORT, 2, _buildS(4+numFields, argvec), NN);
free((char *)argvec);
/*
* Build the abstract type for the instances.
*/
opSigSeq = F_NewNode(T_SEQUENCE, 9);
opSigSeq->nChildren = 9;
iAT = BSR("instanceAT", -1);
opSigSeq->b.children[0] = buildSignature(
BON("=", -1), iAT, NN, builtinBoolean, NN);
opSigSeq->b.children[1] = buildSignature(
BON("!=", -1), iAT, NN, builtinBoolean, NN);
opSigSeq->b.children[2] = buildSignature(
BON("<", -1), iAT, NN, builtinBoolean, NN);
opSigSeq->b.children[3] = buildSignature(
BON("<=", -1), iAT, NN, builtinBoolean, NN);
opSigSeq->b.children[4] = buildSignature(
BON(">", -1), iAT, NN, builtinBoolean, NN);
opSigSeq->b.children[5] = buildSignature(
BON(">=", -1), iAT, NN, builtinBoolean, NN);
opSigSeq->b.children[6] = buildSignature(
BON("succ", -1), NN, iAT, NN);
opSigSeq->b.children[7] = buildSignature(
BON("pred", -1), NN, iAT, NN);
opSigSeq->b.children[8] = buildSignature(
BON("ord", -1), NN, builtinInteger, NN);
for (i = 0; i < 9; i++) {
opSigSeq->b.children[i]->b.opsig.isFunction = TRUE;
}
instanceAT = Construct(P_ATLIT, 4,
buildString(currentFileName),
NULL,
BSD("instanceAT", -1),
opSigSeq);
typeO->b.oblit.decls = buildS(1,
Construct(P_CONSTDECL, 3, BSD("instanceAT", -1), NN, instanceAT));
typeO->b.oblit.monitor = NN;
/* Build the operations on the type. */
/* build the getSignature operation on the type. */
typeO->b.oblit.ops = F_NewNode(T_SEQUENCE, 4+numFields);
typeO->b.oblit.ops->nChildren = 4+numFields;
od = Construct(P_OPDEF, 2,
buildSignature(BON("getsignature", -1), NN, builtinPAT, NN),
buildBlock(BSR("r", 0), BSR("instanceAT", -1), NN));
od->b.opdef.sig->b.opsig.isFunction = TRUE;
typeO->b.oblit.ops->b.children[0] = od;
/* build the creation signature */
createSig = buildSignature(BON("create", -1), builtinInteger, NN, BSR("instanceAT", -1), NN);
createSig->b.opsig.isFunction = TRUE;
/* build the instanceO. */
instanceO = F_NewNode(P_OBLIT, 10);
instanceO->nChildren += 10;
instanceO->b.oblit.sfname = buildString(currentFileName);
instanceO->b.oblit.name = BSD("anEnum", 1);
exportSeq = Construct(T_SEQUENCE, 9, BON("=", -1), BON("!=", -1),
BON("<", -1), BON("<=", -1), BON(">", -1), BON(">=", -1),
BON("succ", -1), BON("pred", -1), BON("ord", -1));
instanceO->b.oblit.export = Construct(P_EXPORT, 2, exportSeq, NN);
instanceO->b.oblit.decls = NN;
monitorO = F_NewNode(P_MONITOR, 4);
monitorO->nChildren += 4;
varDecls = buildS(1,
Construct(P_VARDECL, 3, BSD("l", 0), builtinInteger, NN));
opDecls = F_NewNode(T_SEQUENCE, 9);
opDecls->nChildren += 9;
for (i = 0; i < 6; i++) {
opDecls->b.children[i] = Construct(P_OPDEF, 2,
copySig(opSigSeq->b.children[i]),
buildBlock(
BSR("r", 0),
buildInvocation(
BSR("l", 0),
opSigSeq->b.children[i]->b.opsig.name,
1,
buildInvocation(
BSR("p", 0),
BON("ord", -1),
0)),
NN));
}
/* build succ */
s1 = Construct(P_ASSERTSTAT, 1,
buildInvocation(
BSR("l", 0),
BON("<", -1),
1,
buildIntegerLiteral(numFields-1)));
s2 = Construct(P_ASSIGNSTAT, 3,
buildS(1, BSR("r", 0)),
(NodePtr) OASSIGN,
buildS(1, buildInvocation(
BSR("enum", 0),
BON("create", -1),
1,
buildInvocation(
BSR("l", 0),
BON("+", -1),
1,
buildIntegerLiteral(1)))));
block = Construct(P_BLOCK, 3, buildS(2, s1, s2), NN, NN);
opDecls->b.children[6]= Construct(P_OPDEF, 2,
copySig(opSigSeq->b.children[6]),
block);
/* build pred */
s1 = Construct(P_ASSERTSTAT, 1,
buildInvocation(
BSR("l", 0),
BON(">", -1),
1,
buildIntegerLiteral(0)));
s2 = Construct(P_ASSIGNSTAT, 3,
buildS(1, BSR("r", 0)),
(NodePtr) OASSIGN,
buildS(1, buildInvocation(
BSR("enum", 0),
BON("create", -1),
1,
buildInvocation(
BSR("l", 0),
BON("-", -1),
1,
buildIntegerLiteral(1)))));
block = Construct(P_BLOCK, 3, buildS(2, s1, s2), NN, NN);
opDecls->b.children[7]= Construct(P_OPDEF, 2,
copySig(opSigSeq->b.children[7]),
block);
/* build ord */
opDecls->b.children[8]= Construct(P_OPDEF, 2,
copySig(opSigSeq->b.children[8]),
buildBlock(BSR("r", 0), BSR("l", 0), NN));
monitorO->b.monitor.decls = varDecls;
monitorO->b.monitor.ops = opDecls;
monitorO->b.monitor.init = Construct(P_INITDEF, 1,
buildBlock(BSR("l", 0), BSR("p", 0), NN));
monitorO->b.monitor.recovery = NN;
monitorO->b.monitor.mayBeElided = TRUE;
instanceO->b.oblit.monitor = monitorO;
instanceO->b.oblit.ops = NN;
instanceO->b.oblit.process = NN;
typeO->b.oblit.ops->b.children[1] = Construct(P_OPDEF, 2,
createSig,
buildBlock(BSR("r", 0), instanceO, NN));
/* first operation on type */
sig = buildSignature(BON("first", -1), NN, BSR("instanceAT", -1), NN);
sig->b.opsig.isFunction = TRUE;
typeO->b.oblit.ops->b.children[2] = Construct(P_OPDEF, 2,
sig,
buildBlock(
BSR("r", 0),
buildInvocation(
Construct(P_SELFLIT, 0),
BON("create", 0),
1,
buildIntegerLiteral(0)),
NN));
/* last operation on type */
sig = buildSignature(BON("last", -1), NN, BSR("instanceAT", -1), NN);
sig->b.opsig.isFunction = TRUE;
typeO->b.oblit.ops->b.children[3] = Construct(P_OPDEF, 2,
sig,
buildBlock(
BSR("r", 0),
buildInvocation(
Construct(P_SELFLIT, 0),
BON("create", 0),
1,
buildIntegerLiteral(numFields - 1)),
NN));
/* all the other creation operations on the type */
for (i = 0; i < numFields; i++) {
thisField = p->b.enumlit.syms->b.children[i];
sig = buildSignature(
BON(Ident_Name(thisField->b.symdef.ident), -1),
NN,
BSR("instanceAT", -1),
NN);
sig->b.opsig.isFunction = TRUE;
typeO->b.oblit.ops->b.children[4+i] = Construct(
P_OPDEF,
2,
sig,
buildBlock(
BSR("r", 0),
buildInvocation(
Construct(P_SELFLIT, 0),
BON("create", 0),
1,
buildIntegerLiteral(i)),
NN));
}
typeO->b.oblit.process = NN;
typeO->b.oblit.f.immutable = TRUE;
instanceO->b.oblit.f.immutable = TRUE;
*fNodePtr = typeO;
removeSugar(fNodePtr);
return;
/*break;*/
case P_UNIONLIT:
break;
case P_RECORDLIT:
isImmutable = p->b.recordlit.f.immutable;
factor = isImmutable ? 1 : 2;
typeO = F_NewNode(P_OBLIT, 10);
typeO->nChildren += 10;
typeO->b.oblit.sfname = buildString(currentFileName);
typeO->b.oblit.name = p->b.recordlit.name;
typeO->b.oblit.export = Construct(P_EXPORT, 2,
buildS(3, BON("getsignature", -1), BON("create", -1),BON("new", -1)),
NN);
/*
* Build the abstract type for the instances.
*/
assert(p->b.recordlit.fields->tag == T_SEQUENCE);
numFields = p->b.recordlit.fields->nChildren;
opSigSeq = F_NewNode(T_SEQUENCE, factor * numFields);
opSigSeq->nChildren = factor * numFields;
for (i = 0; i < numFields; i++) {
thisField = p->b.recordlit.fields->b.children[i];
opSigSeq->b.children[factor * i] = buildSignature(
BON("get", thisField->b.vardecl.sym->b.symdef.ident),
NN /* trailer for args */,
thisField->b.vardecl.type,
NN /* trailer for results */);
opSigSeq->b.children[factor * i]->b.opsig.isFunction = TRUE;
if (! isImmutable) {
opSigSeq->b.children[factor * i + 1] = buildSignature(
BON("set", thisField->b.vardecl.sym->b.symdef.ident),
thisField->b.vardecl.type,
NN,
NN);
opSigSeq->b.children[factor*i+1]->b.opsig.isFunction = FALSE;
}
}
instanceAT = Construct(
P_ATLIT,
4,
NULL,
NULL,
BSD("instanceAT", -1),
opSigSeq);
instanceAT->b.atlit.f.immutable = isImmutable;
typeO->b.oblit.decls = buildS(1, Construct(P_CONSTDECL, 3,
BSD("instanceAT", -1),
NN,
instanceAT));
typeO->b.oblit.monitor = NN;
/*
* The operations on the type.
*/
typeO->b.oblit.ops = buildS(3, NN, NN);
od = Construct(P_OPDEF, 2,
buildSignature(BON("getsignature", -1), NN, builtinPAT, NN),
buildBlock(BSR("r", 0), BSR("instanceAT", -1), NN));
od->b.opdef.sig->b.opsig.isFunction = TRUE;
typeO->b.oblit.ops->b.children[0] = od;
/* build "new" */
/* use r */
r = p->b.recordlit.fields;
argvec = (NodePtr *)
malloc((unsigned)(sizeof(NodePtr)*(r->nChildren)));
for (i = 0; i < r->nChildren; i++) {
argvec[i] = Construct(P_NILLIT, 0);
}
od = Construct(P_OPDEF, 2,
buildSignature(BON("new", -1), NN, BSR("instanceAT", -1), NN),
buildBlock(BSR("r", 0),
_buildInvocation(
Construct(P_SELFLIT, 0),
BON("create", 0),
r->nChildren,
argvec),
NN));
typeO->b.oblit.ops->b.children[2] = od;
/* end use r */
/* build "create" */
/* use r */
r = p->b.recordlit.fields;
argvec = (NodePtr *)
malloc((unsigned)(sizeof(NodePtr)*(r->nChildren + 3)));
for (i = 0; i < r->nChildren; i++) {
argvec[i] = r->b.children[i]->b.vardecl.type;
}
/* end use r */
argvec[i++] = 0;
argvec[i++] = BSR("instanceAT", -1);
argvec[i++] = 0;
createSig = _buildSignature(BON("create", -1), argvec);
free((char *)argvec);
/* build the instanceO. */
instanceO = F_NewNode(P_OBLIT, 10);
instanceO->nChildren += 10;
instanceO->b.oblit.sfname = buildString(currentFileName);
instanceO->b.oblit.name =
buildComplicatedSymbol(P_SYMDEF,
"a",
typeO->b.oblit.name->b.symdef.ident,
"record");
exportSeq = F_NewNode(T_SEQUENCE, numFields * factor);
exportSeq->nChildren = numFields * factor;
instanceO->b.oblit.export = Construct(P_EXPORT, 2, exportSeq, NN);
instanceO->b.oblit.decls = NN;
monitorO = F_NewNode(P_MONITOR, 4);
monitorO->nChildren += 4;
varDecls = F_NewNode(T_SEQUENCE, numFields);
varDecls->nChildren = numFields;
opDecls = F_NewNode(T_SEQUENCE, factor * numFields);
opDecls->nChildren = factor * numFields;
for (i = 0; i < numFields; i++) {
thisField = p->b.recordlit.fields->b.children[i];
exportSeq->b.children[factor*i+0] =
opSigSeq->b.children[factor*i+0]->b.opsig.name;
if (!isImmutable) {
exportSeq->b.children[factor*i+1] =
opSigSeq->b.children[factor*i+1]->b.opsig.name;
}
varDecls->b.children[i] = Construct(P_VARDECL, 3,
BSD("l", i),
thisField->b.vardecl.type,
Construct(P_SYMREF, 0));
varDecls->b.children[i]->b.vardecl.isAttached = thisField->b.vardecl.isAttached;
varDecls->b.children[i]->b.vardecl.value->b.symref.ident =
createSig->b.opsig.params->b.children[i]->b.param.sym
->b.symdef.ident;
opDecls->b.children[factor*i+0] = Construct(P_OPDEF, 2,
copySig(opSigSeq->b.children[factor*i+0]),
buildBlock(BSR("r", 0), BSR("l", i), NN));
if (!isImmutable) {
opDecls->b.children[factor*i+1] = Construct(P_OPDEF, 2,
copySig(opSigSeq->b.children[factor*i+1]),
buildBlock(BSR("l", i), BSR("p", 0), NN));
}
}
monitorO->b.monitor.decls = varDecls;
monitorO->b.monitor.ops = opDecls;
monitorO->b.monitor.mayBeElided = TRUE;
monitorO->b.monitor.init = NN;
monitorO->b.monitor.recovery = NN;
instanceO->b.oblit.monitor = monitorO;
instanceO->b.oblit.ops = NN;
instanceO->b.oblit.process = NN;
typeO->b.oblit.ops->b.children[1] = Construct(P_OPDEF, 2,
createSig,
buildBlock(BSR("r", 0), instanceO, NN));
typeO->b.oblit.process = NN;
typeO->b.oblit.f.immutable = TRUE;
instanceO->b.oblit.f.immutable = isImmutable;
instanceO->b.oblit.f.resultsDependOnlyOnArgs = TRUE;
*fNodePtr = typeO;
removeSugar(fNodePtr);
return;
/*break;*/
default:
break;
}
p = *fNodePtr;
for (i = p->firstChild; i < p->nChildren; i++) {
removeSugar(&(p->b.children[i]));
}
}
}
/*VARARGS2*/
static NodePtr buildS(n, first)
int n;
NodePtr first;
{
return(_buildS(n, &first));
}
static NodePtr _buildS(n, args)
register int n;
register NodePtr *args;
{
register NodePtr p;
register int i;
if (n == 0) return(NN);
p = F_NewNode(T_SEQUENCE, n);
p->nChildren = n;
for (i = 0; i < n; i++) p->b.children[i] = args[i];
return(p);
}
static void fixParams(p, prefix)
register NodePtr p;
char *prefix;
{
register int i;
register NodePtr r;
if (p == NN) return;
for (i = 0; i < p->nChildren; i++) {
r = BSD(prefix, i);
r = Construct(P_PARAM, 3, r, p->b.children[i], NULL);
r->b.param.move = FALSE;
p->b.children[i] = r;
}
}
/*VARARGS2*/
static NodePtr buildSignature(opName, first)
NodePtr opName;
NodePtr first;
{
return (_buildSignature(opName, &first));
}
static NodePtr _buildSignature(opName, args)
NodePtr opName;
NodePtr *args;
{
NodePtr result;
NodePtr *params, *results;
int nParams, nResults;
register int i;
i = 0;
params = &args[i];
nParams = 0;
while (args[i]) {
nParams++;
i++;
}
i++;
results = &args[i];
nResults = 0;
while (args[i]) {
nResults++;
i++;
}
result = Construct(P_OPSIG, 4,
opName,
_buildS(nParams, params),
_buildS(nResults, results),
NN);
fixParams(result->b.opsig.params, "p");
fixParams(result->b.opsig.results, "r");
return (result);
}
/*VARARGS1*/
static NodePtr buildBlock(first)
NodePtr first;
{
return(_buildBlock(&first));
}
static NodePtr _buildBlock(args)
NodePtr *args;
{
register NodePtr result;
int nStatements = 0;
register int i;
for (i = 0; args[i] != NN; i += 2) nStatements ++;
result = F_NewNode(T_SEQUENCE, nStatements);
result->nChildren = nStatements;
for (i = 0; i < nStatements; i++) {
result->b.children[i] = Construct(P_ASSIGNSTAT, 3,
buildS(1, args[2*i+0]),
(NodePtr) OASSIGN,
buildS(1, args[2*i+1]));
}
result = Construct(P_BLOCK, 3, result, NN, NN);
return(result);
}